package com.keta.foundation.shiro;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.keta.foundation.constants.Constants;
import com.keta.foundation.controller.IndexController;
import com.keta.foundation.util.Exceptions;

public class CaptchFormAuthenticationFilter extends FormAuthenticationFilter {

	private static final Logger log = LoggerFactory.getLogger(CaptchFormAuthenticationFilter.class);

	// 是否使用验证码功能
	private boolean useCaptcha;
	// 是否使用记住我功能
	private boolean useRememberMe;

	public boolean isUseCaptcha() {
		return useCaptcha;
	}

	public void setUseCaptcha(boolean useCaptcha) {
		this.useCaptcha = useCaptcha;
	}

	public boolean isUseRememberMe() {
		return useRememberMe;
	}

	public void setUseRememberMe(boolean useRememberMe) {
		this.useRememberMe = useRememberMe;
	}

	@Override
	protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {

		// 通过Filter链传递userCaptcha到login.jsp页面进行JSTL解析
		request.setAttribute("userCaptcha", useCaptcha);
		request.setAttribute("useRememberMe", useRememberMe);

		// 避免不能多次登录的情况(暂时不清楚什么原理)
		if (isLoginSubmission(request, response)) {
			return false;
		}

		return super.isAccessAllowed(request, response, mappedValue);
	}

	@Override
	protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {

		String username = getUsername(request);
		String password = getPassword(request);
		String captcha = request.getParameter(Constants.CAPTCHA_KEY);
		boolean rememberMe = isRememberMe(request);
		String host = getHost(request);

		CaptchaUsernamePasswordToken token = new CaptchaUsernamePasswordToken(username, password, rememberMe, host,
				captcha);
		token.setUseCaptcha(useCaptcha);

		return token;
	}

	/**
	 * 登录成功时回调该方法，做跳转到SuccessUrl
	 */
	@Override
	protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
			ServletResponse response) throws Exception {

		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;

		// 加入ipAddress
		ShiroUser shiroUser = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
		shiroUser.setIpAddress(request.getRemoteAddr());

		if (!"XMLHttpRequest".equalsIgnoreCase(httpRequest.getHeader("X-Requested-With"))
				|| request.getParameter("ajax") == null) {// 不是ajax请求
			httpResponse.sendRedirect(httpRequest.getContextPath() + this.getSuccessUrl());
		} else {
			httpResponse.sendRedirect(httpRequest.getContextPath() + "/login/timeout/success");
		}

		return false;
	}

	/**
	 * 认证失败调用该方法
	 */
	@Override
	protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request,
			ServletResponse response) {

		log.info(e.getStackTrace().toString());

		return super.onLoginFailure(token, e, request, response);
	}

}
